/**
 * Created by Ganother on 2017/4/5.
 */
function selector (select, Aparent) {
  let parent = Aparent || document
  let realSelector
  if (select.indexOf('#') !== -1) {
    realSelector = select.slice(1)
    return parent.getElementById(realSelector)
  } else if (select.indexOf('.') !== -1) {
    realSelector = select.slice(1)
    return parent.querySelectorAll(realSelector)
  } else {
    return parent.getElementsByTagName(select)
  }
}
const canvas = selector('#canvas')
const ctx = canvas.getContext('2d')

ctx.globalCompositeOperation = 'source-atop'

// 兼容3倍retina屏， 需要把canvas画布大小设为物理大小的3倍，否则会模糊
const RATIO = 2

const tool = selector('#tool')
const tool2 = selector('#tool2')

const toolHeight = tool.offsetHeight
let canvasOffset = canvas.getBoundingClientRect()
const canvasWidth = canvas.width = canvasOffset.width * RATIO
const canvasHeight = canvas.height = (canvasOffset.width ) * RATIO
canvas.style.height = canvasWidth / RATIO + 'px'
canvasOffset = canvas.getBoundingClientRect()

// 初始背景白布
ctx.fillStyle = "#fff";
ctx.fillRect(0, 0, canvasWidth, canvasHeight)

let lastImageData = []

// 坐标转换 相对窗口坐标变为canvas实际坐标
function windowToCanvas (x, y) {
  return {
    x: (x - canvasOffset.left) * (canvasWidth / canvasOffset.width),
    y: (y - canvasOffset.top) * (canvasHeight / canvasOffset.height)
  }
}

// 获取鼠标canvas坐标
function getTouchPosition (e) {
  let touch = e.changedTouches[0]
  return windowToCanvas(touch.clientX, touch.clientY)
}
// 鼠标点击canvas坐标的对称点坐标
function getTouchPositionD (e) {
  let touch = e.changedTouches[0]
  var zb = windowToCanvas(touch.clientX, touch.clientY)
  return {
    x: canvasWidth - zb.x,
    y: zb.y
  }
}

// 储存画布信息（用于撤回）
function saveImageData (data) {
  (lastImageData.length == 5) && (lastImageData.shift())
  lastImageData.push(data)
}

// 工具基础 宽度，颜色，是否在绘画中，是否被选中
class Basic {
  constructor (width = RATIO, color = '#000') {
    this.width = width
    this.color = color
    this.drawing = false
    this.isSelect = false
  }
}

//铅笔类 通过简单的路径描点连线
class Pencil extends Basic {
  constructor (width = RATIO, color = '#000') {
    super(width, color)
    this.name = 'pencil'
    this.dom = selector(`#${this.name}`)
  }
  begin (loc) {
    saveImageData(ctx.getImageData(0, 0, canvasWidth, canvasHeight))
    // 先保存画布状态，再改变画布状态
    ctx.save()
    ctx.lineWidth = this.width
    ctx.strokeStyle = this.color
    ctx.beginPath()
    ctx.moveTo(loc.x, loc.y)
  }
  draw (loc) {
    ctx.lineTo(loc.x, loc.y)
    ctx.stroke()
  }
  end (loc) {
    ctx.lineTo(loc.x, loc.y)
    ctx.stroke()
    // 恢复到之前的画布状态
    ctx.restore()
  }
  bindEvent () {
    canvas.addEventListener('touchstart', (e) => {
      e.preventDefault()
      if (!this.isSelect) {
        return false
      }
      this.drawing = true
      let loc = getTouchPosition(e)
      this.begin(loc)
    })
    canvas.addEventListener('touchmove', (e) => {
      e.preventDefault()
      if (!this.isSelect) {
        return false
      }
      if (this.drawing) {
        let loc = getTouchPosition(e)
        this.draw(loc)
      }
    })
    canvas.addEventListener('touchend', (e) => {
      e.preventDefault()
      if (!this.isSelect) {
        return false
      }
      let loc = getTouchPosition(e)
      this.end(loc)
      this.drawing = false
    })
  }
}

// 橡皮 颜色为背景色的铅笔
class Eraser extends Pencil {
  constructor (width) {
    super(width, '#fff')
    this.name = 'eraser'
    this.dom = selector(`#${this.name}`)
  }
}

// 清空
class Clear extends Basic {
  constructor (width) {
    super(width, '#fff')
    this.name = 'clr'
    this.dom = selector(`#${this.name}`)
  }
  bindEvent(){
    // ctx.clearRect(0,0,1000,1000);
  }
}

// 撤回
class Cancel extends Basic{
  constructor (width) {
    super(width, '#fff')
    this.name = 'cancel'
    this.dom = selector(`#${this.name}`)
  }
  bindEvent(){}
}

// 左右对称
class Zuoyou extends Basic{
  constructor (width = RATIO, color = '#000') {
    super(width, color)
    this.name = 'zuoyou'
    this.dom = selector(`#${this.name}`)
  }
  begin () {
    saveImageData(ctx.getImageData(0, 0, canvasWidth, canvasHeight))
    // 先保存画布状态，再改变画布状态
    ctx.save()
    ctx.lineWidth = this.width
    ctx.strokeStyle = this.color
    ctx.beginPath()
  }
  draw2 (loc) {
    ctx.moveTo(loc.bx, loc.by)
    ctx.lineTo(loc.ex, loc.ey)
    loc.bx = loc.ex
    loc.by = loc.ey
    ctx.stroke()
  }
  bindEvent () {
    var dot = [
      // 鼠标点
      {
        bx:0,
        by:0,
        ex:0,
        ey:0,
      },
      // 对称点
      {
        bx:0,
        by:0,
        ex:0,
        ey:0,
      }
    ]
    canvas.addEventListener('touchstart', (e) => {
      e.preventDefault()
      if (!this.isSelect) {
        return false
      }
      this.drawing = true

      this.begin()

      let loc = getTouchPosition(e)
      let dloc = getTouchPositionD(e)
      dot[0].bx = loc.x
      dot[0].by = loc.y
      dot[1].bx = dloc.x
      dot[1].by = dloc.y
    })
    canvas.addEventListener('touchmove', (e) => {
      e.preventDefault()
      if (!this.isSelect) {
        return false
      }
      if (this.drawing) {
        let loc = getTouchPosition(e)
        let dloc = getTouchPositionD(e)
        dot[0].ex = loc.x
        dot[0].ey = loc.y
        dot[1].ex = dloc.x
        dot[1].ey = dloc.y
        this.draw2(dot[0])
        this.draw2(dot[1])
      }
    })
  }
}

// 中心对称
class Zhongxin extends Basic{
  //  问题线条  7 11  13  14  16  17
  constructor (width = RATIO, color = '#000') {
    super(width, color)
    this.name = 'zhongxin'
    this.dom = selector(`#${this.name}`)
  }
  getNum(){
    var num = 6;

    var sel = document.getElementById("zhongxinSelect"); //定位id

    var index = sel.selectedIndex; // 选中索引

    var num = sel.options[index].value; // 选中值

    return num
  }

  begin () {
    saveImageData(ctx.getImageData(0, 0, canvasWidth, canvasHeight))
    // 先保存画布状态，再改变画布状态
    ctx.save()
    ctx.lineWidth = this.width
    ctx.strokeStyle = this.color
    ctx.beginPath()
  }
  
  drawFn(op , num) {
    // 线条数量
    // var num = 12

    var deg = Math.floor(360 / num);
    var that = this
    for (var i = 0, l = 360; i < l; i += deg) {
        this.drawRotate(i / 180 * Math.PI, function(ctx) {
            that.draw(op);
        });
    }
  }
  drawRotate(deg, fn, _ctx) {
      _ctx = _ctx || ctx
      _ctx.save();
      _ctx.translate(canvas.width / 2, canvas.height / 2);
      _ctx.rotate(deg);
      fn && fn(_ctx);
      _ctx.restore();
  }
  draw(option, _ctx) {
      _ctx = _ctx || ctx;
      _ctx.beginPath();
      _ctx.moveTo(option.bx - canvas.width / 2, option.by - canvas.height / 2);
      _ctx.lineTo(option.ex - canvas.width / 2, option.ey - canvas.height / 2);
      _ctx.stroke();
  }
  
  bindEvent () {

    var num = this.getNum()

    var sel = document.getElementById("zhongxinSelect")
    var that = this
    sel.onchange = function(){
      num = that.getNum()
    }

    var dot = [
      // 鼠标点
      {
        bx:0,
        by:0,
        ex:0,
        ey:0,
      }
    ]

    canvas.addEventListener('touchstart', (e) => {
      e.preventDefault()
      if (!this.isSelect) {
        return false
      }
      this.begin()
      this.drawing = true
      let loc = getTouchPosition(e)
      dot[0].ex = dot[0].bx = loc.x
      dot[0].ey = dot[0].by = loc.y
    })
    canvas.addEventListener('touchmove', (e) => {
      e.preventDefault()
      if (!this.isSelect) {
        return false
      }
      if (this.drawing) {
        let loc = getTouchPosition(e)
        let dloc = getTouchPositionD(e)
        dot[0].bx = dot[0].ex
        dot[0].by = dot[0].ey
        dot[0].ex = loc.x
        dot[0].ey = loc.y
        this.drawFn(dot[0] , num)
      }
    })
  }
}

// 旋转对称
class Xuanzhuan extends Basic{
  constructor (width = RATIO, color = '#000') {
    super(width, color)
    this.name = 'xuanzhuan'
    this.dom = selector(`#${this.name}`)
  }
  getNum(){
    var num = 6;

    // num = document.getElementById("centerNum")
    var sel = document.getElementById("xuanzhuanSelect"); //定位id

    var index = sel.selectedIndex; // 选中索引

    var num = sel.options[index].value; // 选中值

    // this.isSelect = true
    return num
  }
  begin () {
    saveImageData(ctx.getImageData(0, 0, canvasWidth, canvasHeight))
    // 先保存画布状态，再改变画布状态
    ctx.save()
    ctx.lineWidth = this.width
    ctx.strokeStyle = this.color
    ctx.beginPath()
  }
  
  drawFn(op , num) {
    // 线条数量
    // var num = 6

    var deg = Math.floor(360 / num);
    var that = this
    for (var i = 0, l = 360; i < l; i += deg) {
        this.drawRotate(i / 180 * Math.PI, function(ctx) {
            that.draw(op);
        });
    }
  }
  drawRotate(deg, fn, _ctx) {
      _ctx = _ctx || ctx
      _ctx.save();
      _ctx.translate(canvas.width / 2, canvas.height / 2);
      _ctx.rotate(deg);
      fn && fn(_ctx);
      _ctx.restore();
  }
  draw(option, _ctx) {
      _ctx = _ctx || ctx;
      _ctx.beginPath();
      _ctx.moveTo(option.bx - canvas.width / 2, option.by - canvas.height / 2);
      _ctx.lineTo(option.ex - canvas.width / 2, option.ey - canvas.height / 2);
      _ctx.stroke();
  }
  
  bindEvent () {
    var num = this.getNum()

    var sel = document.getElementById("xuanzhuanSelect")
    var that = this
    sel.onchange = function(){
      num = that.getNum()
    }

    var dot = [
      // 鼠标点
      {
        bx:0,
        by:0,
        ex:0,
        ey:0,
      },
      // 对称点
      {
        bx:0,
        by:0,
        ex:0,
        ey:0,
      }
    ]

    canvas.addEventListener('touchstart', (e) => {
      e.preventDefault()
      if (!this.isSelect) {
        return false
      }
      this.begin()
      this.drawing = true
      let loc = getTouchPosition(e)
      dot[0].ex = dot[0].bx = loc.x
      dot[0].ey = dot[0].by = loc.y
      //
      let dloc = getTouchPositionD(e)
      dot[1].ex = dot[1].bx = dloc.x
      dot[1].ey = dot[1].by = dloc.y
    })
    canvas.addEventListener('touchmove', (e) => {
      e.preventDefault()
      if (!this.isSelect) {
        return false
      }
      if (this.drawing) {
        let loc = getTouchPosition(e)
        let dloc = getTouchPositionD(e)
        dot[0].bx = dot[0].ex
        dot[0].by = dot[0].ey
        dot[0].ex = loc.x
        dot[0].ey = loc.y
        //
        dot[1].bx = dot[1].ex
        dot[1].by = dot[1].ey
        dot[1].ex = dloc.x
        dot[1].ey = dloc.y
        this.drawFn(dot[0] , num)
        this.drawFn(dot[1] , num)
      }
    })
  }
}

// 整合绘图工具
class Tool {
  constructor () {
    this.pencil = new Pencil(RATIO, '#000')
    this.eraser = new Eraser(RATIO * 10)
    this.zuoyou = new Zuoyou()
    this.zhongxin = new Zhongxin()
    this.xuanzhuan = new Xuanzhuan()
    this.clr = new Clear()
    this.cancel = new Cancel()

    let allTools = [this.pencil, this.eraser, this.zuoyou, this.zhongxin, this.xuanzhuan, this.clr, this.cancel]
    // 设置watcher 改变工具时改变工具的isSelected属性
    Object.defineProperty(this, 'selected', {
      set : function (value) {
        for (let item of allTools) {
          if (item.name === value) {
            item.isSelect = true
            item.dom.style.color = '#f00'
          } else {
            item.isSelect = false
            item.dom.style.color = '#000'
          }
        }
      },
      get : function () {
        for (let item of allTools) {
          if (item.isSelect) {
            return item.name
          }
        }
      }
    })
  }
  bindEvent () {
    var beforeSelect = 'pencil'
    this.selected = 'pencil'
    var isEraser = false

    var beforeEraser = 'pencil'

    tool.addEventListener('click', (e) => {
      let target = e.target
      let name = target.getAttribute('id')
      if(name !== 'clr'){
        beforeSelect = this.selected
        this.selected = name
      }
      // 点击上锁的模式 => 之前模式
      if(name == 'zhongxinlock'){
        this.selected = beforeSelect
      }
      // 中心对称的下拉框 => 中心对称
      if(name == 'zhongxinSelect'){
        this.selected = 'zhongxin'
      }
      // 旋转对称的下拉框 => 旋转对称
      if(name == 'xuanzhuanSelect'){
        this.selected = 'xuanzhuan'
      }

      lineWidth.range.value = this[name].width / RATIO
      if (name === 'eraser') {
        return false
      }
      if (name === 'clr') {
        ctx.clearRect(0,0,canvasWidth,canvasHeight);
        // 加底色
        ctx.fillStyle = "#fff";
        ctx.fillRect(0, 0, canvasWidth, canvasHeight)
        //
        return false
      }

      palette.entrance.style.color = this[name].color
    })
    tool2.addEventListener('click', (e) => {
      let target = e.target
      let name = target.getAttribute('id')
      if(name !== 'clr'){
        if(name == 'eraser' && isEraser == false){
          beforeEraser = this.selected
        }
        beforeSelect = this.selected
        this.selected = name
      }
      lineWidth.range.value = this[name].width / RATIO

      if (name === 'eraser') {
        if (isEraser) {
          this.selected = beforeEraser
        }
        isEraser = !isEraser
        return false
      }
      if (name === 'clr') {
        // alert("456");
        // 清空
        ctx.clearRect(0,0,canvasWidth,canvasHeight);
        // 加底色
        ctx.fillStyle = "#fff";
        ctx.fillRect(0, 0, canvasWidth, canvasHeight)
        // 
        this.selected = beforeSelect
        // console.log(beforeSelect)
        return false
      }
      if (name == 'cancel') {
        if(lastImageData.length < 1) {
          alert("只能撤销最近5次操作")
          this.selected = beforeSelect
          return false
        }
        ctx.putImageData(lastImageData[lastImageData.length - 1], 0, 0)
        lastImageData.pop()

        this.selected = beforeSelect
      }

      palette.entrance.style.color = this[name].color
    })
    this.pencil.bindEvent()
    this.eraser.bindEvent()
    this.zuoyou.bindEvent()
    this.zhongxin.bindEvent()
    this.xuanzhuan.bindEvent()
    this.cancel.bindEvent()
  }
}

//调色板
class Palette {
  constructor () {
    this.dom = selector("#Palette")
    this.entrance = selector("#toPalette")
    this.show = false
  }
  bindEvent () {
    var beforeColor = ''
    this.dom.addEventListener('click', (e) => {
      const target = e.target
      if (target === this.entrance) {
        this.show = !this.show
        if (this.show) {
          this.dom.className = 'palette palette-show'
        } else {
          this.dom.className = 'palette'
        }
      } else if (target.className.indexOf('item') !== -1) {

        // console.log(tools[tools.selected].name)

        if (tools[tools.selected].name === 'eraser') {
          return false
        }

        const color = window.getComputedStyle(target, null).backgroundColor
        this.entrance.style.color = color
        tools[tools.selected].color = color

        
        // console.log(this.entrance.style.color)
      }
    })
  }
}

//长度选择
class LineWidth {
  constructor () {
    this.dom = selector("#width")
    this.entrance = selector("#toWidth")
    this.range = selector("#lineWidth")
    this.show = false
  }
  bindEvent () {
    this.entrance.addEventListener('click', (e) => {
      this.show = !this.show
      if (this.show) {
        this.dom.className = 'width width-show'
      } else {
        this.dom.className = 'width '
      }
    })
    this.range.addEventListener('change', (e) => {
      const width = this.range.value
      tools[tools.selected].width = width * RATIO
    })
  }
}

function changeSpeed() {
  var value = $('#lineWidth').val();
  var valStr = value*5 + "% 100%";
  $('#value1').css({
    width:value,
    height:value,
    marginLeft:-value/2,
    marginTop:-value/2
  })
  $('#lineWidth').css({
    "background-size": valStr
  })
  $("#lineWidth").val((value / 1).toFixed(0));
};

// 确定模式
var moshiLists = $(".tool_Item")
for(let i = 0 ; i < moshiLists.length ; i ++){
  moshiLists.eq(i).click(function(){
    $(".tool-bar img").removeClass("actived");
    this.firstElementChild.className = 'actived';
  })
}
// 确定颜色
var yanseList = $(".item")
for(let i = 0 ; i < yanseList.length ; i ++){
  yanseList.eq(i).click(function(){
    $(".scroll i").removeClass("actived")
    this.classList.add("actived")
  })
}

// 动态调整操作区域
var canvasH = canvas.height / 2 + 40
$("#caozuoArea").css({
  height:window.innerHeight - canvasH
})

const tools = new Tool()
const palette = new Palette()
const lineWidth = new LineWidth()

lineWidth.bindEvent()
palette.bindEvent()
tools.bindEvent()

// 获取浏览器url参数
function GetRequest() {   
  var url = location.search;
  var theRequest = new Object();   
  if (url.indexOf("?") != -1) {   
     var str = url.substr(1);   
     strs = str.split("&");   
     for(var i = 0; i < strs.length; i ++) {   
        theRequest[strs[i].split("=")[0]]=unescape(strs[i].split("=")[1]);   
     }   
  }   
  return theRequest;   
}
var level = this.GetRequest()['level']
if(level == 1){
  // 已转发过，去掉上锁图片
  $("#zhongxin").removeAttr('hidden');
  $("#zhongxinSelect").removeAttr('hidden');
  $("#zhongxinlock").attr('hidden','hidden');
}

;(function (ctx) {
  // 分享解锁
  selector("#zhongxinlock").addEventListener('click', () => {
    if(level == 0){
      // 跳转转发解锁页面
      wx.miniProgram.navigateTo({
        url: '/pages/unlock/unlock',
        success: function () {
          console.log('success')
        }
      });
    }
  })
  selector("#saveImg").addEventListener('click', () => {
    handleSave();
      function handleSave() {
        //导出base64格式的图片数据
        var base64Data = canvas.toDataURL("image/jpeg", 0.5);
        //封装blob对象
        var blob = base64Data;
        //组装formdata
        var fd = new FormData();
        fd.append("fileName", "tupian0810.jpg");
        fd.append("fileData", blob);//fileData为自定义

        $.post({
          url: 'https://xcx.nanxuncn.cn/api/canvas/mopan/base64',
          type: 'post',
          data: fd,
          contentType: false, // 注意这里应设为false
          processData: false,
          async: false,
          cache: false,
          success: function (data) {
            console.log(data)
            wx.miniProgram.navigateTo({
              url: '/pages/download/download?imgUrl=' + data,
              success: function () {
                console.log('success')
              },
              fail: function () {
                console.log('fail');
              },
              complete: function () {
                console.log('complete');
              }
            });
          },
          error: function (err) {
            console.log(err);
          }
        })
      };

  })
})(ctx)
